import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import matplotlib as mpl

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def save_df_to_csv(df,saving_path,drop=False):
    df = df.reset_index(drop=drop)
    df.to_csv('{}.csv'.format(saving_path),index=False)

def log1p_transform(df,columns):
    res_df = df[columns].apply(lambda x:np.log1p(x))
    return res_df

def display_features_distribution(df,plot_func=sns.histplot,fig_n_cols=4):
    fig_n_rows = df.shape[1]//fig_n_cols + 1
    plt.figure(figsize=(fig_n_cols*10,fig_n_rows*6))
    columns = df.columns
    for idx,col in enumerate(columns):
        plt.subplot(fig_n_rows,fig_n_cols,idx+1)
        plot_func(df,x=col,kde=True,fill=True,label=col)
    plt.xticks(rotation=90)
    plt.legend()
    # plt.savefig('display_features_distribution_hist.png',bbox_inches='tight',pad_inches=0)
    plt.show()


def draw_heatmap(df,figsize=(24,24)):
    plt.figure(figsize=figsize)
    corr = df.corr()
    sns.heatmap(corr,annot=True,square=True,linewidths=0.1,fmt='.2f')
    plt.show()


def graph_component_silhouette(n_clusters, lim_x, mat_size, sample_silhouette_values, clusters):
    #plt.rcParams["patch.force_edgecolor"] = True
    plt.style.use('fivethirtyeight')
    mpl.rc('patch', edgecolor = 'dimgray', linewidth=1)
    
    fig, ax1 = plt.subplots(1, 1)
    fig.set_size_inches(8, 8)
    ax1.set_xlim([lim_x[0], lim_x[1]])
    ax1.set_ylim([0, mat_size + (n_clusters + 1) * 10])
    y_lower = 10
    for i in range(n_clusters):
        
        # 对属于聚类i的样本进行求取轮廓系数，并对其进行排序
        ith_cluster_silhouette_values = sample_silhouette_values[clusters == i]
        ith_cluster_silhouette_values.sort()
        size_cluster_i = ith_cluster_silhouette_values.shape[0]
        y_upper = y_lower + size_cluster_i
        # color = cm.spectral(float(i) / n_clusters) facecolor=color, edgecolor=color,       
        ax1.fill_betweenx(np.arange(y_lower, y_upper), 0, ith_cluster_silhouette_values, alpha=0.8)
        
        # 在轮廓系数图的中间用簇号标记
        ax1.text(-0.03, y_lower + 0.5 * size_cluster_i, str(i), color = 'red', fontweight = 'bold',
                bbox=dict(facecolor='white', edgecolor='black', boxstyle='round, pad=0.3'))
       
        # 为下一个图计算新的y_lower
        y_lower = y_upper + 10  